#include"blockingqueue.h"

#include<stdlib.h>
#include<sys/time.h>
/*
void iter_test(void *data){
    printf("iter test list:%d\n",*((int*)data));
}*/

blockingqueue* create_blockingqueue(){
    blockingqueue* this=(blockingqueue*)calloc(1,sizeof(blockingqueue));
    this->is_empty=1;
    this->queue=create_list();
    this->cond=(pthread_cond_t)PTHREAD_COND_INITIALIZER;
    this->mutex=(pthread_mutex_t)PTHREAD_MUTEX_INITIALIZER;
    return this;
}

void* bq_poll(blockingqueue* this){
    if(this==NULL)return NULL;
    pthread_mutex_lock(&this->mutex);
    while(this->is_empty){
        pthread_cond_wait(&this->cond,&this->mutex);
    }
    void* data=this->queue->data;
    this->queue=delete_node(this->queue,0);
    if(is_list_empty(this->queue)){
        this->is_empty=1;
    }
    pthread_mutex_unlock(&this->mutex);
    return data;
}

void* bq_ub_poll(blockingqueue* this,u_int32_t wait_sec){
    if(this==NULL)return NULL;
    struct timespec wait_time;
    struct timeval now;
    gettimeofday(&now,NULL);
    wait_time.tv_sec=now.tv_sec+wait_sec;
    wait_time.tv_nsec=now.tv_usec;
    pthread_mutex_lock(&this->mutex);
    if(this->is_empty){
        pthread_cond_timedwait(&this->cond,&this->mutex,&wait_time);
    }

    void * data=NULL;
    if(!this->is_empty){
        data=this->queue->data;
        this->queue=delete_node(this->queue,0);
        if(is_list_empty(this->queue)){
            this->is_empty=1;
        }
    }

    pthread_mutex_unlock(&this->mutex);
    return data;
}

void bq_push(blockingqueue* this,void* data){
    if(this==NULL || data==NULL)return ;
    pthread_mutex_lock(&this->mutex);
    this->queue=add_node(this->queue,data);
    if(this->is_empty){
        this->is_empty=0;
    }
    pthread_cond_broadcast(&this->cond);
    pthread_mutex_unlock(&this->mutex);
}

void destory_bk_queue(blockingqueue* this){
    clear_list(this->queue);
    pthread_mutex_destroy(&this->mutex);
    pthread_cond_destroy(&this->cond);
}


